package com.liu.seckill.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liu.seckill.pojo.Order;
import com.liu.seckill.pojo.SeckillMessage;
import com.liu.seckill.pojo.SeckillOrder;
import com.liu.seckill.pojo.User;
import com.liu.seckill.rabbitmq.MQSender;
import com.liu.seckill.service.IGoodsService;
import com.liu.seckill.service.IOrderService;
import com.liu.seckill.service.ISeckillOrderService;
import com.liu.seckill.util.JsonUtil;
import com.liu.seckill.vo.GoodsVo;
import com.liu.seckill.vo.RespBean;
import com.liu.seckill.vo.RespBeanEnum;
import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName SeckillController
 * @Author ：name
 * @Date ：2022-02-16 15:16
 * @Description：
 * @Version: 1.0
 */
@Controller
@RequestMapping("/seckill")
@Slf4j
public class SeckillController  implements InitializingBean {
 @Autowired
  private IOrderService orderService;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private ISeckillOrderService seckillOrderService;

    @Autowired
     private RedisTemplate redisTemplate;

    @Autowired
    private MQSender mqSender;

    private Map<Long, Boolean> EmptyStockMap = new HashMap<>();

    @RequestMapping(value = "/doSeckill",method = RequestMethod.POST)
    @ResponseBody
    public RespBean doSeckill( User user, Long goodsId) {

        if (user==null){
            return RespBean.error(RespBeanEnum.SESSION_ERROR);
        }


      /*  GoodsVo goods = goodsService.findGoodsVoByGoodsId(goodsId);
        log.info("库存剩余：{}",goods.getStockCount());
        //判断库存
        if (goods.getStockCount()<1){

            log.info("库存剩余不足");
          return RespBean.error(RespBeanEnum.EMPTY_STOCK);
        }

        String seckillOrderJson=(String)redisTemplate.opsForValue().get("order:" + user.getId() + ":" + goodsId);
        if (!StringUtils.isEmpty(seckillOrderJson)) {
             return RespBean.error(RespBeanEnum.REPEATE_ERROR);
           }

        Order order = orderService.seckill(user, goods);

      return RespBean.success(order);

       */
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //判断是否重复抢购
        String seckillOrderJson = (String) valueOperations.get("order:" + user.getId() + ":" + goodsId);

        if(!StringUtils.isEmpty(seckillOrderJson)){
            return RespBean.error(RespBeanEnum.REPEATE_ERROR);
        }
        //内存标记,减少Redis访问
        if (null!=EmptyStockMap.get(goodsId) &&EmptyStockMap.get(goodsId)) {
            return RespBean.error(RespBeanEnum.EMPTY_STOCK);
        }
        //预减库存
        Long stock = valueOperations.decrement("seckillGoods:"+ goodsId);
        if (stock<0){
            EmptyStockMap.put(goodsId,true);
            valueOperations.increment("seckillGoods:"+goodsId);
            return RespBean.error(RespBeanEnum.EMPTY_STOCK);
        }
        // 请求入队，立即返回排队中
        SeckillMessage message = new SeckillMessage(user, goodsId);
        mqSender.sendsecKillMessage(JsonUtil.object2JsonStr(message));
        return RespBean.success(0);

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVo> list = goodsService.findGoodsVo();
        if (CollectionUtils.isEmpty(list)){
            return;
        }
        list.stream().forEach(goodsVo -> {
            log.info("初始化庫存"+goodsVo.getId()+":"+goodsVo.getStockCount());
            redisTemplate.opsForValue().set("seckillGoods:" + goodsVo.getId(),goodsVo.getStockCount());
            EmptyStockMap.put(goodsVo.getId(), false);
        });

    }

    /**
     * 获取秒杀结果
     *
     * @param user
     * @param goodsId
     * @return orderId:成功，-1：秒杀失败，0：排队中
     */
    @RequestMapping(value = "/result", method = RequestMethod.GET)
    @ResponseBody
    public RespBean getResult(User user, Long goodsId) {
          if (user == null) {
           return RespBean.error(RespBeanEnum.SESSION_ERROR);
          }
          Long orderId = seckillOrderService.getResult(user, goodsId);
          return RespBean.success(orderId);
            }

}
